package com.dkha.server.services.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dkha.common.enums.ApiUrlEnum;
import com.dkha.common.exception.DkException;
import com.dkha.common.fileupload.MinioUtil;
import com.dkha.common.http.HttpUtil;
import com.dkha.common.modules.vo.ReturnVO;
import com.dkha.common.modules.vo.face.ApiFaceOneSearchFaceVO;
import com.dkha.common.modules.vo.face.ApiFaceOneSearchReturnFaceVO;
import com.dkha.common.modules.vo.face.ApiFaceSearGroupReturnVO;
import com.dkha.common.modules.vo.face.ApiSearchFaceRectVO;
import com.dkha.common.modules.vo.facelib.*;
import com.dkha.common.modules.vo.search.FaceCheckVO;
import com.dkha.common.modules.vo.search.FaceCompareVO;
import com.dkha.common.util.Base64ImageUtils;
import com.dkha.common.util.JsonUtil;
import com.dkha.common.util.UtilValidate;
import com.dkha.server.services.ICompareService;
import com.dkha.server.services.IFileService;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @Author Spring
 * @Since 2019/12/11 16:12
 * @Description 比对相关业务类
 */
@Component
public class CompareServiceImpl implements ICompareService {

    @Value("${api.group.max}")
    private String apiGroupMaxSize;
    @Value("${api.server.prefix}")
    private String apiServerPrefix;
    @Value("${api.group.min}")
    private int apiGroupMinSize;
    @Autowired
    private HttpUtil httpUtil;
//    @Autowired
//    private Base64ImageUtils base64ImageUtils;
    @Autowired
    private MinioUtil minioUtil;
    @Autowired
    private IFileService iFileService;
    @Value("${api.server.prefix}")
    private String apiRequestPrefix;
    /**
     * 比对的图片数量
     */
    public static int comparePicSize = 2;

    @Override
    public CompareResultVo groupingCompare(CompareRequestVo compareRequestVo) {
        if (UtilValidate.isEmpty(compareRequestVo.getUrlList())) {
            throw new DkException("请选择需要比对的图片");
        }
        if (compareRequestVo.getUrlList().size() < apiGroupMinSize) {
            throw new DkException("请至少选择" + apiGroupMinSize + "张图片进行分组");
        }
        if (compareRequestVo.getUrlList().size() > Integer.parseInt(apiGroupMaxSize)) {
            throw new DkException("最多只支持"+ apiGroupMaxSize +"张图片分组");
        }
        //调用sdk进行分组
        FaceCheckVO faceCheckVO = new FaceCheckVO();
        if (UtilValidate.isNotEmpty(compareRequestVo.getMinScore())) {
            faceCheckVO.setMinScore(compareRequestVo.getMinScore());
        }
        faceCheckVO.setImgs(compareRequestVo.getUrlList());
        String apiUrl = apiServerPrefix + ApiUrlEnum.FACE_GROUP.getUrl();
        ReturnVO returnVO = (ReturnVO)httpUtil.post(apiUrl, faceCheckVO, ReturnVO.class);
        List<List<ApiFaceSearGroupReturnVO>> resultList = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference<List<List<ApiFaceSearGroupReturnVO>>>() {});
        //返回结果集
        CompareResultVo compareResultVo = new CompareResultVo();
        if (UtilValidate.isNotEmpty(resultList)) {
            for (List<ApiFaceSearGroupReturnVO> apiFaceSearGroupReturnVOList : resultList) {
                CompareResultSubVo compareResultSubVo = new CompareResultSubVo();
                //取返回回来的第一张图片作为左侧比对标准
                compareResultSubVo.setResultUrl(apiFaceSearGroupReturnVOList.get(0).getUrl());
                for (int i = 1; i < apiFaceSearGroupReturnVOList.size(); i++) {
                    CompareResultDetailVo compareResultDetailVo = new CompareResultDetailVo();
                    compareResultDetailVo.setScore(apiFaceSearGroupReturnVOList.get(i).getHitSimilarity());
                    compareResultDetailVo.setUrl(apiFaceSearGroupReturnVOList.get(i).getUrl());
                    compareResultSubVo.getCompareResultSubVoList().add(compareResultDetailVo);
                }
                compareResultVo.getCompareResultSubVoList().add(compareResultSubVo);
            }
        }
        return compareResultVo;
    }

    @Override
    public OneToOneResultVo oneToOne(CompareRequestVo compareRequestVo) {
        if (UtilValidate.isEmpty(compareRequestVo.getUrlList())) {
            throw new DkException("请选择需要比对的图片");
        }
        if (compareRequestVo.getUrlList().size() != comparePicSize) {
            throw new DkException("请上传1:1比对的两张图片");
        }

        String apiUrl = apiServerPrefix + ApiUrlEnum.FACE_COMPARISON.getUrl();
        // String apiUrltest = "http://192.168.1.196:5001/compare";
        FaceCompareVO faceCompareVO = new FaceCompareVO();
        faceCompareVO.setImage1(compareRequestVo.getUrlList().get(0));
        faceCompareVO.setImage2(compareRequestVo.getUrlList().get(1));
        System.out.println();
        ReturnVO returnVO = (ReturnVO)httpUtil.post(apiUrl, faceCompareVO, ReturnVO.class);
        ApiFaceOneSearchReturnFaceVO apiFaceOneSearchReturnFaceVO = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference<ApiFaceOneSearchReturnFaceVO>() {});
        //返回结果集
        OneToOneResultVo oneToOneResultVo = new OneToOneResultVo();
        if (UtilValidate.isNotEmpty(apiFaceOneSearchReturnFaceVO)) {
            oneToOneResultVo.getUrls().add(faceCompareVO.getImage1());
            oneToOneResultVo.getUrls().add(faceCompareVO.getImage2());
            oneToOneResultVo.setScore(apiFaceOneSearchReturnFaceVO.getHitSimilarity());
        }
//        if (UtilValidate.isNotEmpty(apiFaceOneSearchReturnFaceVO)) {
//            if (UtilValidate.isNotEmpty(apiFaceOneSearchReturnFaceVO.getFaces())) {
//                for (ApiFaceOneSearchFaceVO apiFaceOneSearchFaceVO : apiFaceOneSearchReturnFaceVO.getFaces()) {
//                    oneToOneResultVo.getUrls().add(apiFaceOneSearchFaceVO.getUrl());
//                }
//                oneToOneResultVo.setScore(apiFaceOneSearchReturnFaceVO.getHitSimilarity());
//            }
//        }
        return oneToOneResultVo;
    }

    @Override
    public String setFaceCompare(String image) {
        JSONObject map1;
        try {
            map1 = minioUtil.uploadFiles(Base64ImageUtils.BaseToInputStream(image), String.valueOf(getHash() % 500), String.valueOf(getHash()), ".jpg");
        } catch (Exception e) {
            e.printStackTrace();
            throw new DkException("文件上传失败");
        }
        String imag = map1.getString("url");
        //人脸检测方法入口
        validateSingleFaceImage(imag);
        return imag;

    }

    /**
     * 返回hash值
     * @return
     */
    public int getHash(){
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        int hash = uuid.hashCode();
        if(hash<0){
            hash = 0-hash;
        }
        return hash;
    }
    /**
     * 多图/单图上传,其中一张图可以多人脸/单人脸 校验
     * @param image
     */
    private void validateSingleFaceImage(String image) {
        //人脸检测url
        String faceSearchUrl = apiRequestPrefix + ApiUrlEnum.FACE_SEARCH.getUrl();
        //String faceSearchUrltest ="http://192.168.3.123:5001/message/mask";
        //组装api请求数据
        ReturnVO returnVO = (ReturnVO) httpUtil.post(faceSearchUrl + "?url=" + image, null, ReturnVO.class);
        System.out.println(returnVO.getCode()+returnVO.getMessage());
        if (returnVO.getCode() != 200) {
            throw new DkException(returnVO.getMessage());
        }
        //反序列化
        // 返回data格式{
        //    "code": 200,
        //    "data": [
        //        {
        //            "faceRect": {
        //                "h": 174,
        //                "w": 257,
        //                "x": 161,
        //                "y": 47
        //            },
        //            "url": "http://192.168.1.133:9000/middleware/456/1790226920.jpg"
        //        }
        //    ],
        //    "message": "检测到人脸"
        //}
        List<ApiSearchFaceRectVO> apiSearchFaceRectVOList = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference<List<ApiSearchFaceRectVO>>() {});
        if (UtilValidate.isEmpty(apiSearchFaceRectVOList)) {
            throw new DkException("当前上传中未检测到人脸,请重新上传");
        }
        if (apiSearchFaceRectVOList.size() > 1) {
            throw new DkException("当前上传图片检测到多张人脸,请重新上传");
        }
    }
    //上传图片
    public   FaceCompareVO setFaceCompare(String image1,String image2) {
        FaceCompareVO faceCompareVO = new FaceCompareVO();
        JSONObject map1;
        try {
            map1 = minioUtil.uploadFiles(Base64ImageUtils.BaseToInputStream(image1), String.valueOf(getHash() % 500), String.valueOf(getHash()), null);
            String imag = map1.getString("url");
            validateSingleFaceImage(imag);
            faceCompareVO.setImage1(imag);
        } catch (Exception e) {
            throw new DkException("文件上传失败");
        }

        JSONObject map2;
        try {
            map2 = minioUtil.uploadFiles(Base64ImageUtils.BaseToInputStream(image2), String.valueOf(getHash() % 500), String.valueOf(getHash()), null);
            String image = map2.getString("url");
            validateSingleFaceImage(image);
            faceCompareVO.setImage2(image);
        } catch (Exception e) {
            throw new DkException("文件上传失败");
        }

        return faceCompareVO;
    }
}
